"""
@-*- coding: utf-8 -*-
@ python: 3.12.3
@ 创建者: JacksonCode
@ 创建时间: 2025-11-04
@ 描述: API错误处理
"""
from flask import jsonify
from werkzeug.exceptions import HTTPException
from flask_jwt_extended import JWTManager


def register_error_handlers(app):
    """注册全局错误处理器"""
    
    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            "code": 400,
            "message": "请求参数错误",
            "data": None
        }), 400
    
    @app.errorhandler(401)
    def unauthorized(error):
        return jsonify({
            "code": 401,
            "message": "未授权访问",
            "data": None
        }), 401
    
    @app.errorhandler(403)
    def forbidden(error):
        return jsonify({
            "code": 403,
            "message": "禁止访问",
            "data": None
        }), 403
    
    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "code": 404,
            "message": "资源不存在",
            "data": None
        }), 404
    
    @app.errorhandler(405)
    def method_not_allowed(error):
        return jsonify({
            "code": 405,
            "message": "请求方法不被允许",
            "data": None
        }), 405
    
    @app.errorhandler(422)
    def unprocessable_entity(error):
        return jsonify({
            "code": 422,
            "message": "请求格式正确，但语义错误",
            "data": None
        }), 422
    
    @app.errorhandler(429)
    def ratelimit_handler(error):
        return jsonify({
            "code": 429,
            "message": "请求频率过高，请稍后再试",
            "data": None
        }), 429
    
    @app.errorhandler(500)
    def internal_server_error(error):
        return jsonify({
            "code": 500,
            "message": "服务器内部错误",
            "data": None
        }), 500
    
    @app.errorhandler(Exception)
    def handle_exception(error):
        """处理未捕获的异常"""
        # 如果是HTTP异常，使用它的处理方式
        if isinstance(error, HTTPException):
            return error
        
        # 记录错误日志
        app.logger.error(f"Unhandled Exception: {str(error)}")
        
        # 返回通用错误响应
        return jsonify({
            "code": 500,
            "message": "服务器发生未知错误",
            "data": None
        }), 500


def register_jwt_handlers(jwt):
    """注册JWT错误处理器"""
    
    @jwt.expired_token_loader
    def expired_token_callback(jwt_header, jwt_payload):
        return jsonify({
            "code": 401,
            "message": "令牌已过期",
            "data": None
        }), 401
    
    @jwt.invalid_token_loader
    def invalid_token_callback(error):
        return jsonify({
            "code": 401,
            "message": "令牌无效",
            "data": None
        }), 401
    
    @jwt.unauthorized_loader
    def missing_token_callback(error):
        return jsonify({
            "code": 401,
            "message": "需要提供令牌",
            "data": None
        }), 401
    
    @jwt.needs_fresh_token_loader
    def token_not_fresh_callback(jwt_header, jwt_payload):
        return jsonify({
            "code": 401,
            "message": "需要新的令牌",
            "data": None
        }), 401
    
    @jwt.revoked_token_loader
    def revoked_token_callback(jwt_header, jwt_payload):
        return jsonify({
            "code": 401,
            "message": "令牌已撤销",
            "data": None
        }), 401


class APIError(Exception):
    """自定义API错误类"""
    def __init__(self, message, status_code=400, payload=None):
        super().__init__()
        self.message = message
        self.status_code = status_code
        self.payload = payload
    
    def to_dict(self):
        """转换为字典格式"""
        result = {
            "code": self.status_code,
            "message": self.message,
            "data": self.payload
        }
        return result
